package com.supermarket.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.supermarket.dto.LoginDto;
import com.supermarket.dto.UserPageQueryDto;
import com.supermarket.entity.User;
import com.supermarket.exception.BaseException;
import com.supermarket.mapper.UserMapper;
import com.supermarket.service.UserService;
import com.supermarket.utils.PageResult;
import com.supermarket.vo.LoginVo;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import static com.supermarket.constant.MessageConstant.ACCOUNT_NOT_FOUND;
import static com.supermarket.constant.MessageConstant.VALIDATECODE_ERROR;
import static com.supermarket.constant.RedisConstant.LOGIN_TOKEN_PREFIX;
import static com.supermarket.constant.RedisConstant.LOGIN_VALIDATE_CODE_PREFIX;


@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {

    private final StringRedisTemplate redisTemplate;
    private final UserMapper userMapper;

    @Override
    public LoginVo login(LoginDto loginDto) {
        // 校验验证码
        String inputCaptcha = loginDto.getCaptcha();
        String codeKey = loginDto.getCodeKey();
        String redisCaptcha = redisTemplate.opsForValue().get(LOGIN_VALIDATE_CODE_PREFIX + codeKey);
        if (!StringUtils.hasLength(redisCaptcha) || !inputCaptcha.equalsIgnoreCase(redisCaptcha)) {
            throw new BaseException(VALIDATECODE_ERROR);
        }
        // 删除使用过的验证码
        redisTemplate.delete(LOGIN_VALIDATE_CODE_PREFIX + codeKey);
        // 从数据库查询用户
        User user = userMapper.selectByUserName(loginDto.getUsername());
        if (user == null) {
            throw new BaseException(ACCOUNT_NOT_FOUND);
        }
        // 校验密码
        String md5Password = DigestUtils.md5DigestAsHex(loginDto.getPassword().getBytes());
        if (!md5Password.equals(user.getPassword())) {
            throw new BaseException("密码错误");
        }
        // 生成 token
        String token = UUID.randomUUID().toString().replace("-", "");
        // 将用户信息存入 Redis，并设置过期时间
        redisTemplate.opsForValue().set(LOGIN_TOKEN_PREFIX + token, JSON.toJSONString(user), 30, TimeUnit.MINUTES);
        // 构建登录响应对象
        LoginVo loginVo = new LoginVo();
        loginVo.setToken(token);
        loginVo.setRefresh_token("");  // 如果需要刷新 token，可以在这里添加逻辑
        return loginVo;
    }

    @Override
    public PageResult list(UserPageQueryDto queryDto) {

        PageHelper.startPage(queryDto.getPage(),queryDto.getPageSize());
        List<User> userList = userMapper.queryUserList(queryDto.getUsername(),queryDto.getPhone());
        Page<User> page = (Page<User>) userList;
        return new PageResult(page.getTotal(),page.getResult());
    }

    @Override
    public void addUser(User user) {
        // 密码加密
        user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes()));
        // 设置角色
        user.setStatus(1);
        user.setRole(0);
        // 填充时间字段
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        userMapper.addUser(user);
    }

    @Override
    public void updateUser(User user) {
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateUser(user);
    }

    @Override
    public void deleteUserById(Long id) {
        userMapper.deleteUserById(id);
    }

    @Override
    public void enableOrDisable(Integer status, Long id) {
        User user = User.builder()
                .id(id)
                .status(status)
                .updateTime(LocalDateTime.now())
                .build();
        userMapper.updateUser(user);
    }

    @Override
    public void logout(String token) {
        redisTemplate.delete(LOGIN_TOKEN_PREFIX + token);
    }

    @Override
    public User getByUserId(Long id) {
        return userMapper.getUserById(id);
    }
}
